package com.class5.springboot.frame.repo.tool.xml;

import java.io.Serializable;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@SuppressWarnings("serial")
public class DbTable implements Serializable {
    //逻辑表名
    private String name;
    //数据库节点
    private String[] dbs;
    //数据是否同步到canal
    private boolean canales = false;
    //数据变更是否发布到kafka
    private boolean canalkafka = false;
    //主数据库
    private String masterdb;
    //描述
    private String comment;
    //详细说明
    private String notes;
    //列声明
    private List<DbTableColumn> columns = new ArrayList<>();
    //所有组合索引
    private List<DbTableIndex> indexes = new ArrayList<DbTableIndex>();
    //表对应的实体类
    private String entity;
    //每个数据库节点对应的物理表数量
    private int perNodeNum = 1;
    //代码生成器配置参数：是否生成业务类
    private boolean generateService = true;
    //是否生成实体
    private boolean noentity = false;
    //按key缓存主要是为了提高效率
    private Map<String, DbTableColumn> colMap = null;
    private Map<String, DbTableColumn> fieldMap = null;
    private DbTableColumn identityColumn = null;
    private DbTableColumn versionColumn = null;
    /**
     * 获取真实物理表的名称
     * @return
     */
    public List<String> getRealTables(){
        List<String> ls = new ArrayList<String>();
        if(perNodeNum <= 1){
            ls.add(name);
            return ls;
        }
        for(int i =0; i<perNodeNum; i++){
            ls.add(name + "_" + i);
        }
        return ls;
    }

    public String getMasterdb() {
        return masterdb;
    }
    public void setMasterdb(String masterdb) {
        this.masterdb = masterdb;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getComment() {
        return comment;
    }
    public void setComment(String c) {
        this.comment = c;
    }
    public List<DbTableColumn> getColumns() {
        return columns;
    }
    public void setColumns(List<DbTableColumn> columns) {
        this.columns = columns;
        initCache();
    }
    public DbTableColumn getPrimary() {
        for(DbTableColumn c : columns) {
            if(c.isIdentity()) {
                return c;
            }
        }
        return null;
    }
    private void initCache() {
        colMap = new HashMap<String, DbTableColumn>();
        fieldMap = new HashMap<String, DbTableColumn>();
        for(DbTableColumn c : columns){
            colMap.put(c.getName(), c);
            fieldMap.put(c.getField(), c);
            if(c.isIdentity() && identityColumn != null){
                throw new RuntimeException("目前只支持一张表一个identity列");
            }
            if(c.isIdentity()){
                identityColumn = c;
            }
            if(c.isVersion() && versionColumn != null){
                throw new RuntimeException("一张表只能有一个version列");
            }
            if(c.isVersion()){
                versionColumn = c;
            }
        }
        Collections.unmodifiableList(columns);
        Collections.unmodifiableMap(colMap);
        Collections.unmodifiableMap(fieldMap);
    }
    /**
     * 检查是否存在指定列
     * @param col
     * @return
     */
    public boolean hasColumn(String col) {
        return colMap.containsKey(col);
    }
    public List<DbTableIndex> getIndexes() {
        return indexes;
    }
    public void setIndexes(List<DbTableIndex> indexes) {
        this.indexes = indexes;
    }
    public String getEntity() {
        return entity;
    }
    public void setEntity(String entity) {
        this.entity = entity;
    }
    public int getPerNodeNum() {
        return perNodeNum;
    }
    public void setPerNodeNum(int perNodeNum) {
        this.perNodeNum = perNodeNum;
    }
    public DbTableColumn getColumn(String name){
        return colMap.get(name);
    }
    public DbTableIndex getIndex(String name){
        for(DbTableIndex i : indexes){
            if(i.getName().equals(name))
                return i;
        }
        return null;
    }

    protected static String wrapName(String name){
        return "`" + name + "`";
    }
    public String[] getDbs() {
        return dbs;
    }
    public void setDbs(String[] dbs) {
        this.dbs = dbs;
    }
    public DbTableColumn getColumnByField(String field) {
        return fieldMap.get(field);
    }
    public String getNotes() {
        return notes;
    }
    public void setNotes(String notes) {
        this.notes = notes;
    }
    public boolean isGenerateService() {
        return generateService;
    }
    public void setGenerateService(boolean generateService) {
        this.generateService = generateService;
    }
    public boolean isNoentity() {
        return noentity;
    }
    public void setNoentity(boolean noentity) {
        this.noentity = noentity;
    }

    public boolean isCanales() {
        return canales;
    }

    public void setCanales(boolean canales) {
        this.canales = canales;
    }

    public boolean isCanalkafka() {
        return canalkafka;
    }

    public void setCanalkafka(boolean canalkafka) {
        this.canalkafka = canalkafka;
    }
}